function guass(mu, sigma, x){
  var mat = multiply(multiply(minmus(x,mu),inv(sigma)), transpose(minmus(x,mu)))
  
  var mat_ = []
  for(var i=0;i<mat.length;i++){
      for(var j=0;j<mat[0].length;j++){
          if(i==j) mat_.push(mat[i][j])
      }
  }
  
  var n_mat = multiply_num(mat_, -0.5)
  
  var n_mat_ = []
  for(var i=0;i<n_mat.length;i++){
      n_mat_.push(Math.exp(n_mat[i]))
  }
  
  var guass_n = multiply_num(n_mat_, (1/(Math.pow((2*Math.PI),(x[0].length/2))*Math.pow((det(sigma)),(0.5))))) 
  
  return guass_n
}

function minmus(x=[[]],mu=[]){
  var mat = []
  for(var i=0;i<x.length;i++){
      mat.push([])
      for(var j=0;j<x[i].length;j++){
          mat[i].push(x[i][j] - mu[j])
      }
  }

  return mat
}

function adjoint(mat=[]) {
  let n = mat.length;

  let result = new Array(n).fill(0).map(a => new Array(n).fill(0));
  for (let row = 0; row < n; row++) {
      for (let column = 0; column < n; column++) {
          // 去掉第 row 行第 column 列的矩阵
          let matrix = [];
          for (let i = 0; i < mat.length; i++) {
              if (i !== row) {
                  let arr = [];
                  for (let j = 0; j < mat.length; j++) {
                      if (j !== column) {
                          arr.push(mat[i][j]);
                      }
                  }
                  matrix.push(arr);
              }
          }
          result[row][column] = Math.pow(-1, row + column) * det(matrix);
      }
  }
  return transpose(result);
}


function inv(mat=[]) {

  let detValue = det(mat);
  let result = adjoint(mat);
  
  for (let i = 0; i < result.length; i++) {
      for (let j = 0; j < result.length; j++) {
          result[i][j] = result[i][j]/detValue;
      }
  }
  return result;
}


function transpose(matrix) {
  let result = new Array(matrix[0].length).fill(0).map(arr => new Array(matrix.length).fill(0));
  for (let i = 0; i < result.length; i++) {
      for (let j = 0; j < result[0].length; j++) {
          result[i][j] = matrix[j][i];
      }
  }
  return result;
}

function multiply(a, b, x=1) {
  
  let m = a.length;
  let p = a[0].length;
  let n = b[0].length;

  // 初始化 m*n 全 0 二维数组
  let c = new Array(m).fill(0).map(arr => new Array(n).fill(0));

  for (let i = 0; i < m; i++) {
      for (let j = 0; j < n; j++) {
          for (let kk = 0; kk < p; kk++) {
              c[i][j] += a[i][kk] * b[kk][j] * x;
          }
      }
  }

  return c;
}

function multiply_num(a=[], x){
  var mat = []
  for(var i=0;i<a.length;i++){
      mat.push(a[i]*x)
  }

  return mat
}

function det(mat=[]) {
  // 方阵阶数
  let n = mat.length;

  let result = 0;
  if (n > 3) {
      // n 阶
      for (let column = 0; column < n; column++) {
          // 去掉第 0 行第 column 列的矩阵
          let matrix = new Array(n - 1).fill(0).map(arr => new Array(n - 1).fill(0));
          for (let i = 0; i < n - 1; i++) {
              for (let j = 0; j < n - 1; j++) {
                  if (j < column) {
                      matrix[i][j] = mat[i + 1][j];
                  } else {
                      matrix[i][j] = mat[i + 1][j + 1];
                  }
              }
          }
          result += mat[0][column] * Math.pow(-1, 0 + column) * det(matrix);
      }
  } else if (n === 3) {
      // 3 阶
      result = mat[0][0] * mat[1][1] * mat[2][2] +
      mat[0][1] * mat[1][2] * mat[2][0] +
      mat[0][2] * mat[1][0] * mat[2][1] -
      mat[0][2] * mat[1][1] * mat[2][0] -
      mat[0][1] * mat[1][0] * mat[2][2] -
      mat[0][0] * mat[1][2] * mat[2][1];
  } else if (n === 2) {
      // 2 阶
      result = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0];
  } else if (n === 1) {
      // 1 阶
      result = mat[0][0];
  }
  return result;
}

export {guass,minmus,adjoint,inv,transpose,multiply,multiply_num,det};